<?php
/**
 * Lib\Pidguin\Application - class control application
 *
 * @author Eni
 * @version 1.2.1
 */
class Pidguin_Application
{
	protected $_locale = null;
	/**
	 * Object of class config
	 *
	 * @var object Config
	 */
	protected $_config = null;
	
	/**
	 * Instance of class
	 *
	 * @var Pidguin_Application
	 */
	private static $_instance = null;
	
	/**
	 * Get instance of class
	 *
	 * @return Pidguin_Application
	 */
	public static function getInstance()
	{
		if (self::$_instance === null) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}
	
	/**
	 * Construct of class
	 *
	 * @return void
	 */
	public function __construct()
	{
		// register autoloader
		require LIB_PIDGUIN_DIR . DS . 'Autoloader.php';
		Pidguin_Autoloader::registerAutoload();
	}
	
	/**
	 * Set application config
	 *
	 * @return void
	 */
	public function setConfig($fileConfig)
	{
		$this->_config = new Zend_Config_Ini($fileConfig);
		Zend_Registry::set('config', $this->_config);
	}
	
	/**
	 * Get application config
	 *
	 * @return object Zend_Config_Ini
	 */
	public function getConfig($fileConfig)
	{
		return $this->_config;
	}
	
	/**
	 * Execute application
	 *
	 * @return void
	 */
	public function execute()
	{
		$this->_logger();
		$this->_setCache();
		$this->_setDatabase();
		$client = Pidguin_Client::getInstance();
		$client->sessionStart();
		$client->clientIdentity();
		
		$this->_setTranslator();
		
		$front = Zend_Controller_Front::getInstance();
		$front->addModuleDirectory(APP_DIR . DS . 'Modules');
		$front->setDefaultModule('public');
		
		if ($this->_config->debug->enabled == 1) {
			$front->throwExceptions(true);
		}
		
		// Init View Renderer
		$view = new Zend_View();
		$view->headTitle($this->_config->application->name)->setSeparator(' -> ')->setDefaultAttachOrder('PREPEND');
		
		$view->addScriptPath(APP_DIR . DS . 'Layouts');
		$tplFormat = 'php';
		
		$renderer = new Zend_Controller_Action_Helper_ViewRenderer();
		$renderer->setView($view);
		$renderer->setViewSuffix($tplFormat);
		// Set view renderer helper
		Zend_Controller_Action_HelperBroker::addHelper($renderer);
		
		// Init Zend_Layout
		$layout = Zend_Layout::startMvc();
		$layout->setViewSuffix($tplFormat);
		$layout->setLayout('public');
		
		// Init router
		$this->_setRouter($front);
		
		// Init plugins
		$front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
    		'module'     => 'public',
    		'controller' => 'Error',
    		'action'     => 'error'
		)));
		$front->dispatch();		
	}
	
	protected function _setRouter($front)
	{
		if ($this->_config->router->advanced->enabled == 1) {
			$cacheManager = Zend_Registry::get('cache');
			$cache = $cacheManager->getCache('file');
			if (!$routes = $cache->load('Pidguin_DB_Routes')) {
				$model = Model_Router::getInstance();
				$select = $model->select()->from(array('r' => 'router'), array('name', 'route', 'reverse' , 'controller', 'action', 'params'))
					->joinLeft(array('m' => 'modules'), 'r.module=m.id', array('module_name' => 'name'))
					->setIntegrityCheck(false);
				$select->where('enabled = ?', 1);
				
				$routes = $model->fetchAll($select);
				$cache->save($routes, 'Pidguin_DB_Routes');
			}
			//$routes->setTable(Model_Router::getInstance());
			$router = $front->getRouter();
			if ($routes->count()) {
				foreach ($routes as $route) {
					$params = array();
					if ($route->params != '') {
						$route->params = ',' . trim($route->params, ',');
						$paramsRoute = explode(',', $route->params);
						$paramsRouteCount = count($paramsRoute);
						for ($i=1; $i<$paramsRouteCount; $i++) {
							$params[$i] = trim($paramsRoute[$i]);
						}
					}
					$regex = new Zend_Controller_Router_Route_Regex(
								trim($route->route, '/'),
								array(
									'module' => strtolower($route->module_name),
									'controller' => ucfirst($route->controller),
									'action' => ucfirst($route->action)
								),
								$params,
								$route->reverse
							);
					$router->addRoute($route->name, $regex);
				}
			}
			$front->setRouter($router);
		}
	}
	
	/**
	 * Set cache
	 *
	 * @return void
	 */
	protected function _setCache()
	{
		$fcore = array(
			'caching'		=> $this->_config->cache->caching,
			'logging'		=> $this->_config->cache->logging,
			'write_сontrol' => $this->_config->cache->write_control,
			'lifetime'		=> $this->_config->cache->lifetime,
			'automatic_serialization' => $this->_config->cache->automatic_serialization
		);
		// init file cache
		$fcache = Zend_Cache::factory('Core', 'File',
			$fcore,
			array(
				'cache_dir' => ROOT_DIR . DS . $this->_config->cache->file->cache_dir,
				'read_control' => $this->_config->cache->file->read_control,
				'read_control_type' => $this->_config->cache->file->read_control_type,
				'hashed_directory_level' => $this->_config->cache->file->hashed_directory_level,
				'file_name_prefix' => $this->_config->cache->file->file_name_prefix
			)
		);
		// init memcached
		$mcache = Zend_Cache::factory('Core', 'Memcached',
			$fcore,
			array(
				'servers' => array(array(
					'host' => $this->_config->cache->memcached->host,
					'port' => $this->_config->cache->memcached->port,
					'persistent' => $this->_config->cache->memcached->persistent,
					'weight' => intval($this->_config->cache->memcached->weight),
					'timeout' => $this->_config->cache->memcached->timeout,
					'retry_interval' => $this->_config->cache->memcached->retry_interval,
					'status' => $this->_config->cache->memcached->status
				)),
				'compression' => $this->_config->cache->memcached->compression,
				'compatibility' => $this->_config->cache->memcached->compatibility
			)
		);
		$cache = new Zend_Cache_Manager();
		$cache->setCache('file', $fcache);
		$cache->setCache('memcached', $mcache);
		Zend_Registry::set('cache', $cache);
	}
	
	/**
	 * Set database
	 *
	 * @return void
	 */
	protected function _setDatabase()
	{
		$cache = Zend_Registry::get('cache');
		$db = new Zend_Db_Adapter_Pdo_Mysql($this->_config->database->params);
		Zend_Db_Table_Abstract::setDefaultAdapter($db);
		Zend_Db_Table_Abstract::setDefaultMetadataCache($cache->getCache('memcached'));
		Zend_Registry::set('db', $db);
	}
	
	/**
	 * Set logger
	 *
	 * @return void
	 */
	protected function _logger()
	{
		/*$logPath = ROOT_DIR . DS . $this->_config->log->path . DS . 'system.log';
		if (is_file($logPath)) {
			if (filesize($logPath) > 1048576) {
				$copyFile = ROOT_DIR . DS . $this->_config->log->saved_path . DS . 'syste_' . date('Y-m-d') . '.log';
				copy($logPath, $copyFile);
				unlink($logPath);
			}
		}
		
		$log = new Zend_Log(new Zend_Log_Writer_Stream($logPath));
		$log->setTimestampFormat('Y-m-d in H:i:s');
		//$log->registerErrorHandler();
		
		Zend_Registry::set('log', $log);*/
	}
	
	public function setLocale()
	{
		$this->_locale = new Zend_Locale('ru_RU');
	}
	
	public function getLocale()
	{
		if (!$this->_locale) {
			$this->setLocale();
		}
		return $this->_locale;
	}
	
	protected function _setTranslator()
	{
		$translator = new Zend_Translate(
			array(
				'adapter' => 'array',
				'content' => APP_DIR . DS .'Languages' . DS,
				'locale'  => 'ru',
				'scan' => Zend_Translate::LOCALE_DIRECTORY
			)
		);
		Zend_Validate_Abstract::setDefaultTranslator($translator);
	}
}
